#include "qelib.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>


#define STRUPACK_LOG_DOMAIN     "strupack"
#define spk_debug(...)          qelog_debug(STRUPACK_LOG_DOMAIN, __VA_ARGS__)
#define spk_info(...)           qelog_info(STRUPACK_LOG_DOMAIN, __VA_ARGS__)
#define spk_error(...)          qelog_error(STRUPACK_LOG_DOMAIN, __VA_ARGS__)
#define spk_hexdump(...)        qehex_debug(STRUPACK_LOG_DOMAIN, __VA_ARGS__)

#define PACKED             __attribute__((packed))

typedef struct
{
    int a;
    char b;
} PACKED object_cfg;

typedef struct
{
    qe_u32 sta_type;
    qe_u32 sta_id;
    qe_u32 freq_mode;
    qe_u32 freq_val;
    qe_u32 freq_num;
    qe_u32 array_test[16];
    char string_test[32];
    object_cfg obj[2];
} PACKED config;

typedef struct 
{
    qe_u32 magic;
    qe_u32 length;
} PACKED strupack_head;

static void usage()
{
    printf("\n");
    printf("strupack-test <cmd> <opt>\n");
    printf("  -h,?,--help                print help information\n");
    printf("  -i,--input <file>          input file\n");
}

static qe_size get_file_size(const char *name)
{
	qe_size size;
	FILE *fp = fopen(name, "r");
	if (!fp)
		return 0;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	fclose(fp);
	return size;
}

int main(int argc, char *argv[])
{
    int i;
    int opt;
    int size;
    char *input;
    FILE *fp;
    config cfg;
    strupack_head head;

    qelog_init(QELOG_DEBUG, QELOG_CL|QELOG_LV|QELOG_DM|QELOG_HMS);

    static const struct option long_opts[] = {
        {"input", required_argument, QE_NULL, 'i'},
    };

    while ((opt = getopt_long(argc, argv, "i:?h-", long_opts, NULL)) != -1) {
        switch (opt) {
        case 'i':
            input = optarg;
            break;
        case 'h':
        case '?':
        default:
            usage();
            exit(EXIT_SUCCESS);
        }
    }

    size = get_file_size(input);

    fp = fopen(input, "rb");
    if (!fp) {
        spk_error("open file %s failed", input);
        return -1;
    }

    fread(&head, sizeof(strupack_head), 1, fp);
    fread(&cfg, sizeof(cfg), 1, fp);
    fclose(fp);

    spk_hexdump(&head, sizeof(strupack_head));
    spk_hexdump(&cfg, sizeof(cfg));
    spk_debug("magic          : 0x%x", head.magic);
    spk_debug("length         : %d", head.length);
    spk_debug("sta type       : %d", cfg.sta_type);
    spk_debug("sta id         : %d", cfg.sta_id);
    spk_debug("freq mode      : %d", cfg.freq_mode);
    spk_debug("freq val       : %d", cfg.freq_val);
    spk_debug("freq num       : %d", cfg.freq_num);
    for (i=0; i<cfg.freq_num; i++) {
    spk_debug("freq vals[%02d]  : %d", i, cfg.array_test[i]);
    }
    spk_debug("string         : %s", cfg.string_test);
    for (i=0; i<2; i++) {
    spk_debug("obj[%d] a       : %d", i, cfg.obj[i].a);
    spk_debug("obj[%d] b       : %d", i, cfg.obj[i].b);
    }
    
    return 0;
}